import os
from ..core import Builder, MissingParam, BuilderError


class IncludeFileNotFound(BuilderError):
    pass


class CBuilder(Builder):
    PARAMS_PREFIX = "c_"
    
    @classmethod
    def scan(cls, node):
        for line in open(node.filename, "r"):
            line = line.strip()
            if line.startswith("#include"):
                line = line[8:].strip()
                fn = line[1:-1]
                if line.startswith("<"):
                    if not node.params.c_include_path:
                        raise MissingParam("c_include_path")
                    for path in node.params.c_include_path:
                        fullfn = os.path.join(path, fn)
                        if exists(fullfn):
                            node.create_child(fullfn)
                            break
                    else:
                        raise IncludeFileNotFound(node, fn)
                else:
                    node.create_child(fn)
    
    @classmethod
    def get_output_name(cls, node):
        out = node.basename
        ext = node.params.c_toolchain.compile.output_extension
        if ext is not None:
            out += "." + ext
        return out
    
    @classmethod
    def build(cls, node):
        node.params.c_toolchain.compile(node.filename, node.output, node.params)


class HBuilder(CBuilder):
    @classmethod
    def get_output_name(cls, node):
        return None
    
    @classmethod
    def build(cls, node):
        pass


class CppBuilder(CBuilder):
    PARAMS_PREFIX = "cpp_"
    
    @classmethod
    def build(cls, node):
        node.params.c_toolchain.compile(node.filename, node.output, node.params)



def register_builder():
    CBuilder.register("c")
    HBuilder.register("h")
    CppBuilder.register("cc", "cp", "cxx", "cpp", "c++")
    



